﻿module MainApp

open System
open System.Windows
open System.Collections.Generic
open System.IO
open System.IO.Packaging
open System.Xml
open System.Windows.Media.Imaging
open System.Windows.Forms
open System.Windows.Controls
open FSharpx

type MainWindow = XAML<"MainWindow.xaml">


let bitmapList = new List<MemoryStream>()
let isAnimated = ref false
let frameRate = ref 0
let lastFrame = ref 0
let startTime = ref 0L

let modBy x y = y % x


let timer = 
    let t = new System.Windows.Forms.Timer()    
    t.Interval <- 1
    t

let loadWindow() =
    let window = MainWindow()    

    timer.Tick.Add(fun o ->            
        window.Root.Dispatcher.Invoke(fun o -> 
            let currentFrame = 
                10000000L / int64 !frameRate//ticks per frame
                |> (/) (DateTime.Now.Ticks - !startTime)//divide into time since start of play
                |> modBy (int64 bitmapList.Count)
                |> int
                
            if(not (currentFrame = !lastFrame)) then
                bitmapList.[currentFrame].Position <- 0L
                let decoder = new WmpBitmapDecoder(bitmapList.[currentFrame], BitmapCreateOptions.None, BitmapCacheOption.OnLoad)
                window.Image.Source <- decoder.Frames.[0]
            lastFrame := currentFrame
        ))  

    let openFile (filePath:String) =
        use package = Package.Open(filePath)
        let settingXml = new XmlDocument()
        settingXml.Load(package.GetPart(new Uri("/settings.xml", UriKind.Relative)).GetStream())
        isAnimated := bool.Parse(settingXml.DocumentElement.Attributes.["animated"].Value)
        frameRate := Int32.Parse(settingXml.DocumentElement.Attributes.["frameRate"].Value)

        let getImageUri num = new Uri("/" + string num + ".jxr", UriKind.Relative)

        let rec loadImages currentFrame =
            match package.PartExists(getImageUri currentFrame) with
                | false -> ()
                | true ->
                    let jxrStream = package.GetPart(getImageUri currentFrame).GetStream()
                    let memoryStream = new MemoryStream(int jxrStream.Length)
                    jxrStream.CopyTo(memoryStream)
                    bitmapList.Add(memoryStream)
                    loadImages (currentFrame + 1)                    
            
        bitmapList.Clear();
        loadImages 0        
        let decoder = new WmpBitmapDecoder(bitmapList.[0], BitmapCreateOptions.None, BitmapCacheOption.OnLoad)
        window.Image.Width <- float decoder.Frames.[0].PixelWidth
        window.Image.Height <- float decoder.Frames.[0].PixelHeight
        startTime := DateTime.Now.Ticks
        timer.Start()

    window.OpenButton.Click.Add(fun o ->
        let oFD = new OpenFileDialog()
        oFD.Filter <- "Animated JEPG XR files (*.ajxr)|*.ajxr";
        oFD.ShowDialog() |> ignore
        if(File.Exists(oFD.FileName)) then
            openFile oFD.FileName)

    window.Root.Drop.AddHandler(fun o e ->
        if(e.Data.GetDataPresent(System.Windows.Forms.DataFormats.FileDrop)) then
            (e.Data.GetData(System.Windows.Forms.DataFormats.FileDrop) :?> string array).[0]
            |> openFile

        )

    window.Root

[<STAThread>]
(new System.Windows.Application()).Run(loadWindow()) |> ignore